package com.studio49.exmple.service.appInterface.impl;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import com.studio49.exmple.common.SMSUtils.SendSMSTwo;
import com.studio49.exmple.common.SMSUtils.SendSMSUtil;
import com.studio49.exmple.common.constant.ErrorCodeConstant;
import com.studio49.exmple.common.constant.SysConstant;
import com.studio49.exmple.common.util.MD5Utils;
import com.studio49.exmple.common.util.PubAppUtils;
import com.studio49.exmple.common.util.PubDateUtils;
import com.studio49.exmple.core.component.RedisComponent;
import com.studio49.exmple.core.entity.pub.JsonResult;
import com.studio49.exmple.core.service.appInterface.AppBaseService;
import com.studio49.exmple.entity.web.sys.User;
import com.studio49.exmple.mapper.web.sys.UserMapper;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.google.common.collect.Maps;
import com.studio49.exmple.entity.appInterface.appUser.LoginReqEntity;
import com.studio49.exmple.entity.appInterface.appUser.MobileUpdateReqEntity;
import com.studio49.exmple.entity.appInterface.appUser.OpenidLoginReqEntity;
import com.studio49.exmple.entity.appInterface.appUser.RegisterReqEntity;
import com.studio49.exmple.entity.appInterface.appUser.UserNameReqEntity;
import com.studio49.exmple.entity.appInterface.appUser.UuidLoginReqEntity;
import com.studio49.exmple.entity.appInterface.appUser.VerificationCodeLoginReqEntity;
import com.studio49.exmple.entity.appInterface.appUser.VerificationCodeReqEntity;
import com.studio49.exmple.service.appInterface.AppUserService;


@Service("appUserService")
public class AppUserServiceImpl extends AppBaseService implements AppUserService {
	
	@Autowired
	private RedisComponent redisComponent;
	
	@Autowired
	private UserMapper userMapper;
	
	
	@Override
	public JsonResult getVerificationCode(VerificationCodeReqEntity verificationCodeReqEntity) throws Exception {
		JsonResult jsonResult = new JsonResult(true);
		String mobile = verificationCodeReqEntity.getMobile();
		String moduleFlag = verificationCodeReqEntity.getModuleFlag();

		// 先判断redis是否有改手机对应的验证码
		String verificationCodeKey = PubAppUtils.getVerificationCodeKey(moduleFlag, mobile);
		Object code_obj = redisComponent.getData(verificationCodeKey);
		String verificationCode = code_obj == null ? "" : code_obj.toString();

		if (StringUtils.isNotBlank(verificationCode)) {
			// 验证码总有效期3分钟，在1分钟内，不发短信
			long ttl = redisComponent.getExpireTime(verificationCodeKey);
			long d = SysConstant.VERIFICATION_CODE_EFFECTIVE_TIME - 60;
			if (ttl >= d) {
				jsonResult.setErrorCode(ErrorCodeConstant.VERIFICATION_CODE_HAVE_OBTAINED);
				jsonResult.setMsg("已获取过验证码，请稍后再获取!");
				jsonResult.setSuccess(false);
				return jsonResult;
			}
		} else {
			verificationCode = PubAppUtils.getRandomNumber(6);
		}
		Map<String, String> paramMap = Maps.newHashMap();
		paramMap.put("code", verificationCode);
		String[] arr = { mobile };
		SendSMSTwo sendSMSTwo = new SendSMSTwo(null, 1, paramMap, arr);
		boolean flag = SendSMSUtil.sendSMS(sendSMSTwo); //发送验证码
		if (flag) {
			// 短信发送成功，将验证码存入redis，有效时长3分钟
			redisComponent.saveData(verificationCodeKey, verificationCode, SysConstant.VERIFICATION_CODE_EFFECTIVE_TIME);
			jsonResult.setMsg("获取验证码成功!");
			jsonResult.setSuccess(true);
		} else {
			jsonResult.setErrorCode(ErrorCodeConstant.SMS_SEND_FAILED);
			jsonResult.setMsg("短信发送失败!");
			jsonResult.setSuccess(false);
		}
		return jsonResult;
	}
	
	//注册
	@Override
	public JsonResult register(RegisterReqEntity registerReqEntity) throws Exception {
		JsonResult jsonResult = new JsonResult();
		// 判断是否已经注册过
		String mobile = registerReqEntity.getMobile();
		User user_s = new User();
		user_s.setLoginName(mobile);
		user_s.setUserType((short) 1);			//app用户
		List<User> users = userMapper.select(user_s);
		if (CollectionUtils.isNotEmpty(users)) {
			jsonResult.setSuccess(false);
			jsonResult.setMsg("手机号已注册");
			jsonResult.setErrorCode(ErrorCodeConstant.USER_IS_EXISTS);
			return jsonResult;
		}
		
		// 先判断redis是否有改手机对应的验证码
		String verificationCodeKey = PubAppUtils.getVerificationCodeKey(SysConstant.VERIFICATION_CODE_REGISTER, mobile);
		Object code_obj = redisComponent.getData(verificationCodeKey);
		String verificationCode = code_obj == null ? "" : code_obj.toString();
		if(StringUtils.isBlank(verificationCode)) {
			jsonResult.setMsg("验证码已失效！");
			jsonResult.setErrorCode(ErrorCodeConstant.VERIFICATION_CODE_EXPIRED);
			jsonResult.setSuccess(false);
			return jsonResult;
		}
		if(!verificationCode.equals(registerReqEntity.getVerificationCode())) {
			jsonResult.setMsg("验证码错误！");
			jsonResult.setErrorCode(ErrorCodeConstant.VERIFICATION_CODE_ERROR);
			jsonResult.setSuccess(false);
			return jsonResult;
		}
		
		User user_reg = new User();
		user_reg.setLoginName(mobile);
		String passwd_md5 = MD5Utils.md5(registerReqEntity.getPassword());
		user_reg.setPassword(passwd_md5);
		user_reg.setMobile(mobile);
		user_reg.setIsEnable((short) 1);
		user_reg.setUserType((short) 1);
		String randomUUID = UUID.randomUUID().toString();
		user_reg.setUuid(randomUUID);
		userMapper.insertSelective(user_reg);
		
		jsonResult.setMsg("注册成功");
		jsonResult.setSuccess(true);
		return jsonResult;
	}
	
	//手机号登录
	@Override
	public JsonResult mobileLogin(LoginReqEntity loginReqEntity) throws Exception {
		JsonResult jsonResult = new JsonResult(true);
		Map<String, Object> retObj = new HashMap<String, Object>();
		String mobile = loginReqEntity.getMobile();
		String password = loginReqEntity.getPassword();
		// 1.判断用户是否已注册
		User user_s = new User();
		user_s.setLoginName(mobile);
		user_s.setUserType((short) 1);			//app用户
		List<User> users = userMapper.select(user_s);
		if (users == null) {
			jsonResult.setSuccess(false);
			jsonResult.setMsg("手机号未注册");
			jsonResult.setErrorCode(ErrorCodeConstant.USER_NOT_EXISTS);
			return jsonResult;
		}
		User user_res = users.get(0);
		// 2.判断登录名和密码是否正确
		String password_md5 = MD5Utils.md5(password);
		if (!password_md5.equals(user_res.getPassword())) {
			jsonResult.setSuccess(false);
			jsonResult.setMsg("手机号或密码错误");
			jsonResult.setErrorCode(ErrorCodeConstant.ACCOUNT_OR_PASSWD_ERROR);
			return jsonResult;
		}
		// 2.判断用户账号是否冻结
		if (user_res.getIsEnable() == 0) {
			jsonResult.setSuccess(false);
			jsonResult.setMsg("账号已冻结，请联系管理员");
			jsonResult.setErrorCode(ErrorCodeConstant.USER_ACCOUNT_NOT_AVAILABLE);
			return jsonResult;
		}
		
		// 接口返回数据设置
		retObj.put("user", user_res);
//		String tokenKey = PubAppUtils.getTokenKey(loginReqEntity.getDeviceCode(), mobile);
		//存入redis
		String tokenKey = PubAppUtils.getTokenKey(user_res.getId() + "");
		redisComponent.saveData(tokenKey, user_res, SysConstant.DEFUALT_REDIS_EXPIRE);
		
		System.out.println(tokenKey);
		retObj.put("tokenId", tokenKey);
		jsonResult.setObj(retObj);
		
		// 记录日志
//		AppUserLog appUserLogObj = getAppUserLogObj(user);
//		appUserLogService.addAppUserLog(appUserLogObj);
		
		jsonResult.setMsg("登录成功");
		jsonResult.setSuccess(true);
		return jsonResult;
	}
	
	@Override
	public JsonResult verificationCodeLogin(VerificationCodeLoginReqEntity verificationCodeLoginReqEntity) throws Exception {
		JsonResult jsonResult = new JsonResult();
		
		String mobile = verificationCodeLoginReqEntity.getMobile();
		// 先判断redis是否有改手机对应的验证码
		String verificationCodeKey = PubAppUtils.getVerificationCodeKey(SysConstant.VERIFICATION_CODE_VERIFICATION_LOGIN, mobile);
		Object code_obj = redisComponent.getData(verificationCodeKey);
		String verificationCode = code_obj == null ? "" : code_obj.toString();
		if(StringUtils.isBlank(verificationCode)) {
			jsonResult.setMsg("验证码已失效！");
			jsonResult.setErrorCode(ErrorCodeConstant.VERIFICATION_CODE_EXPIRED);
			jsonResult.setSuccess(false);
			return jsonResult;
		}
		if(!verificationCode.equals(verificationCodeLoginReqEntity.getVerificationCode())) {
			jsonResult.setMsg("验证码错误！");
			jsonResult.setErrorCode(ErrorCodeConstant.VERIFICATION_CODE_ERROR);
			jsonResult.setSuccess(false);
			return jsonResult;
		}
		
		Map<String, Object> retObj = new HashMap<String, Object>();
		// 1.判断用户是否已注册
		User user_s = new User();
		user_s.setLoginName(mobile);
		user_s.setUserType((short) 1);			//app用户
		List<User> users = userMapper.select(user_s);
		
		User user = new User();
		if (CollectionUtils.isEmpty(users)) {
			user.setLoginName(mobile);
			String passwd_md5 = MD5Utils.md5("927183");
			user.setPassword(passwd_md5);
			user.setMobile(mobile);
			user.setIsEnable((short) 1);
			user.setUserType((short) 1);
			String randomUUID = UUID.randomUUID().toString();
			user.setUuid(randomUUID);
			userMapper.insertSelective(user);
		}else {
			user = users.get(0);
		}
		
		// 2.判断用户账号是否冻结
		if (user.getIsEnable() == 0) {
			jsonResult.setSuccess(false);
			jsonResult.setMsg("账号已冻结，请联系管理员");
			jsonResult.setErrorCode(ErrorCodeConstant.USER_ACCOUNT_NOT_AVAILABLE);
			return jsonResult;
		}
		
		// 将用户信息存入redis
		String tokenKey = PubAppUtils.getTokenKey(user.getId() + "");
		redisComponent.saveData(tokenKey, user, SysConstant.DEFUALT_REDIS_EXPIRE);
		// 记录日志
//		AppUserLog appUserLogObj = getAppUserLogObj(user);
//		appUserLogService.addAppUserLog(appUserLogObj);
		
		retObj.put("user", user);
		retObj.put("tokenId", tokenKey);
		jsonResult.setObj(retObj);
		jsonResult.setMsg("登录成功");
		jsonResult.setSuccess(true);
		return jsonResult;
	}
	
	/**
	 * uuid登录
	 */
	@Override
	@Transactional
	public JsonResult uuidLogin(UuidLoginReqEntity uuidLoginReqEntity) throws Exception {
		JsonResult jsonResult = new JsonResult();
		
		// 1.判断用户是否已注册
		String uuid = uuidLoginReqEntity.getUuid();
		User user = new User();
		user.setUuid(uuid);
		user.setUserType((short) 1);			//app用户
		List<User> users = userMapper.select(user);
		
		if (CollectionUtils.isEmpty(users)) {
			jsonResult.setErrorCode(ErrorCodeConstant.USER_NOT_EXISTS);
			jsonResult.setMsg("用户不存在！");
			jsonResult.setSuccess(false);
			return jsonResult;
		}
		User user_res = users.get(0);
		Short isEnable = user_res.getIsEnable();
		if("0".equals(isEnable + "")) {
			jsonResult.setErrorCode(ErrorCodeConstant.USER_ACCOUNT_NOT_AVAILABLE);
			jsonResult.setMsg("账号已冻结！");
			jsonResult.setSuccess(false);
			return jsonResult;
		}
		
		//存入redis
		String tokenKey = PubAppUtils.getTokenKey(user_res.getId() + "");
		redisComponent.saveData(tokenKey, user_res, SysConstant.DEFUALT_REDIS_EXPIRE);
		
		// 记录日志
//		AppUserLog appUserLogObj = getAppUserLogObj(user);
//		appUserLogService.addAppUserLog(appUserLogObj);
		
		Map<String, Object> retObj = new HashMap<String, Object>();
		retObj.put("user", user_res);
		retObj.put("tokenId", tokenKey);
		jsonResult.setObj(retObj);
		jsonResult.setMsg("登录成功");
		jsonResult.setSuccess(true);
		
		return jsonResult;
	}

	@Override
	@Transactional
	public JsonResult openidLogin(OpenidLoginReqEntity openidLoginReqEntity) throws Exception {
		JsonResult jsonResult = new JsonResult();

		String openId = openidLoginReqEntity.getOpenId();
		// 1.判断用户是否已注册
		User user_q = new User();
		user_q.setOpenId(openId);
		user_q.setUserType((short) 1);			//app用户
		User user = userMapper.selectOne(user_q);
		//未注册，则注册
		if(user == null) {
			user = new User();
			user.setOpenId(openId);
			user.setUserName(openidLoginReqEntity.getUserName());
			Date now = PubDateUtils.getNow();
			user.setUserType((short) 1);
			user.setCreateTime(now);
			user.setModifyTime(now);
			String randomUUID = UUID.randomUUID().toString();
			user.setUuid(randomUUID);
			userMapper.insertSelective(user);
		}
		
		Short isEnable = user.getIsEnable();
		if("0".equals(isEnable + "")) {
			jsonResult.setErrorCode(ErrorCodeConstant.USER_ACCOUNT_NOT_AVAILABLE);
			jsonResult.setMsg("账号已被冻结，请联系管理员！");
			jsonResult.setSuccess(false);
			return jsonResult;
		}
		
		//存入redis
		String tokenKey = PubAppUtils.getTokenKey(user.getId() + "");
		redisComponent.saveData(tokenKey, user, SysConstant.DEFUALT_REDIS_EXPIRE);
		
		Map<String, Object> retObj = new HashMap<String, Object>();
		retObj.put("user", user);
		retObj.put("tokenId", tokenKey);
		jsonResult.setObj(retObj);
		jsonResult.setMsg("登录成功");
		jsonResult.setSuccess(true);
		return jsonResult;
	}
	
	@Override
	public JsonResult modifyUserName(UserNameReqEntity userNameReqEntity) throws Exception {
		JsonResult jsonResult = new JsonResult();
		User appUser = getAppUser(userNameReqEntity.getTokenId());
		Long appUserId = appUser.getId();
		
		User user = userMapper.selectByPrimaryKey(appUserId);
		if(user == null) {
			jsonResult.setMsg("用户不存在！");
			jsonResult.setErrorCode(ErrorCodeConstant.USER_NOT_EXISTS);
			jsonResult.setSuccess(true);
			return jsonResult;
		}
		user.setUserName(userNameReqEntity.getUserName());
		user.setModifyTime(new Date());
		userMapper.updateByPrimaryKey(user);
		
		jsonResult.setMsg("修改用户名成功！");
		jsonResult.setSuccess(true);
		return jsonResult;
	}

	@Override
	public JsonResult updateMobile(MobileUpdateReqEntity mobileUpdateReqEntity) throws Exception {
		JsonResult jsonResult = new JsonResult();
		User appUser = getAppUser(mobileUpdateReqEntity.getTokenId());
		Long appUserId = appUser.getId();
		
		String mobile = mobileUpdateReqEntity.getMobile();
		// 先判断redis是否有改手机对应的验证码
		String verificationCodeKey = PubAppUtils.getVerificationCodeKey(SysConstant.VERIFICATION_CODE_UPDATE_MOBILE, mobile);
		Object code_obj = redisComponent.getData(verificationCodeKey);
		String verificationCode = code_obj == null ? "" : code_obj.toString();
		if(StringUtils.isEmpty(verificationCode)) {
			jsonResult.setMsg("验证码已失效！");
			jsonResult.setErrorCode(ErrorCodeConstant.VERIFICATION_CODE_EXPIRED);
			jsonResult.setSuccess(false);
			return jsonResult;
		}
		if(!verificationCode.equals(mobileUpdateReqEntity.getVerificationCode())) {
			jsonResult.setMsg("验证码错误！");
			jsonResult.setErrorCode(ErrorCodeConstant.VERIFICATION_CODE_ERROR);
			jsonResult.setSuccess(false);
			return jsonResult;
		}
		
		User user2 = new User();
		user2.setId(appUserId);
		user2.setMobile(mobile);
		user2.setModifyTime(new Date());
		userMapper.updateByPrimaryKeySelective(user2);
		
		jsonResult.setMsg("绑定电话号码成功！");
		jsonResult.setSuccess(true);
		return jsonResult;
	}

	@Override
	public synchronized JsonResult resetPassword(RegisterReqEntity registerReqEntity) throws Exception {
		JsonResult jsonResult = new JsonResult(true);

		// 1.判断用户是否已注册
		String mobile = registerReqEntity.getMobile();
		User user_s = new User();
		user_s.setLoginName(mobile);
		user_s.setUserType((short) 1);			//app用户
		List<User> users = userMapper.select(user_s);

		if (CollectionUtils.isEmpty(users)) {
			jsonResult.setErrorCode(ErrorCodeConstant.USER_NOT_EXISTS);
			jsonResult.setMsg("用户不存在！");
			jsonResult.setSuccess(false);
			return jsonResult;
		}
		User user_res = users.get(0);
		Short isEnable = user_res.getIsEnable();
		// 2.判断用户账号是否冻结
		if("0".equals(isEnable + "")) {
			jsonResult.setErrorCode(ErrorCodeConstant.USER_ACCOUNT_NOT_AVAILABLE);
			jsonResult.setMsg("账号已冻结！");
			jsonResult.setSuccess(false);
			return jsonResult;
		}

		// 3.判断验证码是否已经过期
		String verificationCodeKey = PubAppUtils.getVerificationCodeKey(SysConstant.VERIFICATION_CODE_RESET_PASSWD, registerReqEntity.getMobile());
		Object code_obj = redisComponent.getData(verificationCodeKey);
		String verificationCode = code_obj == null ? "" : code_obj.toString();
		if(StringUtils.isBlank(verificationCode)) {
			jsonResult.setMsg("验证码已失效！");
			jsonResult.setErrorCode(ErrorCodeConstant.VERIFICATION_CODE_EXPIRED);
			jsonResult.setSuccess(false);
			return jsonResult;
		}
		if(!verificationCode.equals(registerReqEntity.getVerificationCode())) {
			jsonResult.setMsg("验证码错误！");
			jsonResult.setErrorCode(ErrorCodeConstant.VERIFICATION_CODE_ERROR);
			jsonResult.setSuccess(false);
			return jsonResult;
		}

		// 修改密码
		String md5Code = MD5Utils.md5(registerReqEntity.getPassword());
		user_res.setPassword(md5Code);
		userMapper.updateByPrimaryKeySelective(user_res);

		jsonResult.setMsg("修改密码成功");
		jsonResult.setSuccess(true);
		return jsonResult;
	}

}
